/**
 * This file is part of Sonedyan.
 * 
 * Sonedyan is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * either version 3 of the License, or (at your option) any
 * later version.
 *
 * Sonedyan is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public
 * License along with Octave; see the file COPYING.  If not
 * see <http://www.gnu.org/licenses/>.
 * 
 * Copyright (C) 2009-2012 Jimmy Dubuisson <jimmy.dubuisson@gmail.com>
 */

package org.unige.mpej.eckmann.sonedyan.enron.db.autoincrement;

import java.util.List;

import org.unige.mpej.eckmann.sonedyan.enron.db.Db4oHandler;

import com.db4o.events.Event4;
import com.db4o.events.EventListener4;
import com.db4o.events.EventRegistry;
import com.db4o.events.EventRegistryFactory;
import com.db4o.events.ObjectEventArgs;
import com.db4o.events.CancellableObjectEventArgs;

/**
 * utils functions to support auto incremented ids
 */
public class AutoIncrementUtils 
{
	/**
	 * get the incremented id instance
	 */
	public static IncrementedId getIncrementedId(Db4oHandler db)
	{
		IncrementedId instance = null;
		
		List<IncrementedId> os = db.getInstancesByClass(IncrementedId.class);
		
		if (os.size() > 0)
		{
			instance = (IncrementedId) os.get(0);
		}
		
		return instance;
	}
	
	/**
	 * register a call back that will increment a counted object id on creation events
	 */
	public static void registerCallback(final Db4oHandler db)
	{
		EventRegistry registry =  EventRegistryFactory.forObjectContainer(db.getContainer());
		
		// register an event handler, which will assign autoincremented IDs to any
		// object extending CountedObject, when the object is created
		registry.creating().addListener(new EventListener4<CancellableObjectEventArgs>()
		{
			public void onEvent(Event4<CancellableObjectEventArgs> e, CancellableObjectEventArgs args) 
			{
				ObjectEventArgs queryArgs = ((ObjectEventArgs) args);
				
				Object obj = queryArgs.object();
				
				// only for the objects extending the CountedObject
				if (obj instanceof CountedObject)
				{
					((CountedObject) obj).setId(getNextId(db));
				}
			}
		});
	}
	
	/**
	 * get the next id
	 * 
	 * @param db
	 * @return
	 */
	private static int getNextId(Db4oHandler db) 
	{
		// this function retrieves the next available ID from 
		// the IncrementedId object
		IncrementedId incrementedId = getInstance(db);   
		return incrementedId.getNextID(db);
	}
	
	/**
	 * get the instance of one of the incremented id subclasses available
	 */
	private static IncrementedId getInstance(Db4oHandler db)
	{
		return IncrementedId.getIdObject(db);
	}
	
}
